package com.shiku.imserver.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JsonKit {
    private static Logger log = LoggerFactory.getLogger(JsonKit.class);
    private static SerializeConfig mapping = new SerializeConfig();

    static {
        mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
        mapping.put(java.sql.Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
        mapping.put(Timestamp.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
        mapping.put(Time.class, new SimpleDateFormatSerializer("HH:mm:ss"));
    }

    public static SerializeConfig put(Class<?> clazz, SerializeFilter filter) {
        mapping.addFilter(clazz, filter);
        return mapping;
    }

    public static SerializeConfig put(Class<?> clazz, ObjectSerializer serializer) {
        mapping.put(clazz, serializer);
        return mapping;
    }

    public static <T> T toBean(String jsonString, Class<T> tt) {
        try {
            if (StringUtils.isBlank(jsonString)) {
                return null;
            }
            return JSON.parseObject(jsonString, tt);
        } catch (Throwable e) {
            log.error("json解析失败:\r\n{}", jsonString);
            throw new RuntimeException(e);
        }
    }

    public static <T> T toBean(byte[] bytes, Class<T> tt) {
        if (bytes == null) {
            return null;
        }
        try {
            return JSON.parseObject(bytes, tt, new Feature[0]);
        } catch (Throwable e) {
            log.error("json解析失败:\r\n{}", bytes);
            throw new RuntimeException(e);
        }
    }

    public static String toFormatedJson(Object bean) {
        try {
            return JSON.toJSONString(bean, mapping, new SerializerFeature[]{SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.PrettyFormat});
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }

    public static String toJSONEnumNoUsingName(Object bean) {
        return JSONObject.toJSONString(bean, SerializerFeature.config(JSON.DEFAULT_GENERATE_FEATURE, SerializerFeature.WriteEnumUsingName, false), new SerializerFeature[0]);
    }

    public static String toJSONString(Object bean, SerializerFeature serializerFeature) {
        return JSONObject.toJSONString(bean, mapping, new SerializerFeature[]{serializerFeature});
    }

    public static String toJSONString(Object bean) {
        try {
            return JSON.toJSONString(bean, mapping, new SerializerFeature[]{SerializerFeature.DisableCircularReferenceDetect});
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }

    public static String toJSONString(Object bean, SerializeFilter serializeFilter) {
        if (serializeFilter != null) {
            try {
                return JSON.toJSONString(bean, mapping, serializeFilter, new SerializerFeature[]{SerializerFeature.DisableCircularReferenceDetect});
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        } else {
            return JSON.toJSONString(bean, mapping, new SerializerFeature[]{SerializerFeature.DisableCircularReferenceDetect});
        }
    }

    public static byte[] toJsonBytes(Object bean) {
        return JSON.toJSONBytes(bean, mapping, new SerializerFeature[]{SerializerFeature.DisableCircularReferenceDetect});
    }

    public static byte[] toJSONBytesEnumNoUsingName(Object bean) {
        return JSONObject.toJSONBytes(bean, SerializerFeature.config(JSON.DEFAULT_GENERATE_FEATURE, SerializerFeature.WriteEnumUsingName, false), new SerializerFeature[0]);
    }

    public static <T> List<T> toArray(List<String> datas, Class<T> clazz) {
        if (datas == null) {
            return null;
        }
        List<T> result = new ArrayList<>();
        for (String obj : datas) {
            result.add(toBean(obj, clazz));
        }
        return result;
    }
}
